/**
 * 
 */
package kulstats;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Query;

/**
 * @author steven
 *
 */
public class ActivityManager {
	//private DAO dao;
	private static final DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
	
	public ActivityManager() { //DAO dao) {
		//this.dao = dao;
	}
	
	
	public void saveActivity(Activity activity, Key key) {
		Entity act = new Entity("Activity", key);
		updateActEntity(act, activity);
		datastore.put(act);
		
	}
	
	private List<Question> getQuestionListFromEntity(Entity actE)
	{
		List<Question> listq = new ArrayList<Question>();
		List<Key> qkeys = (List<Key>)actE.getProperty("Questions");
		if (qkeys != null){
			for (int i = 0; i < qkeys.size(); i++){
				Entity qst = null;
				try {
					qst = datastore.get(qkeys.get(i));
				} catch (EntityNotFoundException e) {
					System.out.println("error entity not found//key::" + qkeys.get(i));
				}
				Map<String, Object> props = qst.getProperties();
				listq.add(new Question(((Number)props.get("QuestionID")).intValue(), (String)props.get("Question")
						,(String)props.get("Answer"), (String)props.get("AnswerList")));
			}
		}
		return listq;
	}
	
	public boolean isAnswered(Activity act)
	{
		for (Question q : act.getQuestionnaire()){
			if (q.getAnswer() != null)
				return true;
		}
		return false;
	}
	
	private Activity retrieveActivity(Entity actE)
	{
		// search all questions, with actkey ancestor to get correct questions
		Key actkey = actE.getKey();
		//List<Question> listq = getQuestionsByActivity(actkey);
		List<Question> listq = getQuestionListFromEntity(actE);
		//System.out.println("retrievetestqkeys:" + qkeys);
		//System.out.println("retrievetestlistq:" + listq);
		
		Activity act = null;
		Map<String, Object> props = actE.getProperties();
		switch(ActivityType.valueOf((String)props.get("ActivityType")))
		{
		// TODO: test question retrieving
			case LESSON:
				 act = new Lesson(actE.getKey(), (Date)props.get("StartDate"), (Date)props.get("StopDate")
					,((Number)props.get("Points")).intValue(), listq
					,Registry.courseManager().getCourseByID((String)props.get("CourseID"))
					, LessonType.valueOf((String)props.get("LessonType")));
				break;
			case SPARE_TIME:
				 act = new SpareTime(actE.getKey(), (Date)props.get("StartDate"), (Date)props.get("StopDate")
						 , listq, SpareTimeType.valueOf((String)props.get("SpareTimeType")));
				break;
			case STUDY:
				 act = new Study(actE.getKey(), (Date)props.get("StartDate"), (Date)props.get("StopDate")
					,((Number)props.get("Points")).intValue(), listq
					,Registry.courseManager().getCourseByID((String)props.get("CourseID"))
					,((Number)props.get("Paused")).intValue(),((Number)props.get("Pauses")).intValue(), (Date)props.get("LastPauseDate"));
				break;
		}
		return act;
	}
	
	private List<Activity> retrieveActivityList(List<Entity> listE)
	{
		List<Activity> list = new ArrayList<Activity>();
		for (int i = 0; i < listE.size(); i++)
		{
			Entity actE = listE.get(i);
			list.add(retrieveActivity(actE));
		}
		
		return list;
	}
	
	public List<Activity> getActivities(Key key) {
		List<Entity> listE = getActivitiesEntity(key, false);
		
		return retrieveActivityList(listE);
	}
	
	public List<Activity> getActivities(Key key,String course) {
		List<Entity> listE = getActivitiesEntityFiltered(key, course);
		
		return retrieveActivityList(listE);
	}
	
	public List<Activity> getActivitiesFiltered(Key key, Date Start, Date Stop) {
		List<Entity> listE = getActivitiesEntityFiltered(key, Start, Stop);
		
		return retrieveActivityList(listE);
	}
	
	public Activity getLastActivity(User user)
	{
		List<Activity> list = new ArrayList<Activity>();
		List<Entity> listE = getActivitiesEntity(user.getKey(), true);
		if (listE != null){
			if(!listE.isEmpty()) {
				Entity actE = listE.get(0);
				return retrieveActivity(actE);
			}
		}
		return null;
	}
	
	private void updateActEntity(Entity actE, Activity act)
	{
		actE.setProperty("ActivityType", act.getAType().toString());
		actE.setProperty("StartDate", act.getStartDate());
		actE.setProperty("StopDate", act.getStopDate());
		actE.setProperty("Points", act.getPoints());
		switch(act.getAType())
		{
			case LESSON:
				actE.setProperty("CourseID", ((Lesson)act).getCourse().getCourseID());
				actE.setProperty("LessonType", ((Lesson)act).getLessontype().toString());
				break;
			case SPARE_TIME:
				actE.setProperty("SpareTimeType", ((SpareTime)act).getType().toString());
				break;
			case STUDY:
				actE.setProperty("CourseID", ((Study)act).getCourse().getCourseID());
				actE.setProperty("Paused", ((Study)act).getPaused());
				actE.setProperty("Pauses", ((Study)act).getPauses());
				actE.setProperty("LastPauseDate", ((Study)act).getLastPauseDate());
				break;
		}
		List<Key> qkeys = (List<Key>)actE.getProperty("Questions");
		List<Question> listq = act.getQuestionnaire();
		if (qkeys == null){ // eerste keer dat object opslaat
			qkeys = new ArrayList<Key>();
			if (listq != null){
				for (int i = 0; i < listq.size(); i++){
					Entity qst = new Entity("Question", act.getKey());
					qst.setProperty("Question", listq.get(i).getQuestion());
					qst.setProperty("QuestionID", listq.get(i).getQuestionID());
					qst.setProperty("Answer", listq.get(i).getAnswer());
					qst.setProperty("AnswerList", listq.get(i).getAnswerlist());
					qkeys.add(datastore.put(qst));
				}
			}
			else{
				qkeys = null;
			}
		}
		else
		{
			Entity qst = null;
			if (listq != null){
				for (int i = 0; i < listq.size(); i++){
					try {
						qst = datastore.get(qkeys.get(i));
					} catch (EntityNotFoundException e) {
						System.out.println("ERROR: entity not found//question::" + qkeys.get(i));
					}
					qst.setProperty("Question", listq.get(i).getQuestion());
					qst.setProperty("QuestionID", listq.get(i).getQuestionID());
					qst.setProperty("Answer", listq.get(i).getAnswer());
					qst.setProperty("AnswerList", listq.get(i).getAnswerlist());
					datastore.put(qst);
				}
			}
			else {
				qkeys = null;
			}
		}
		
		actE.setProperty("Questions", qkeys);
		/*for (int i = 0; i < listq.size(); i++){
			// TODO: check if act.getkey is correct
			Entity qst = new Entity("Question", act.getKey());
			qst.setProperty("Question", listq.get(i).getQuestion());
			qst.setProperty("QuestionID", listq.get(i).getQuestionID());
			qst.setProperty("Answer", listq.get(i).getAnswer());
			qst.setProperty("Answer", listq.get(i).getAnswerlist());
		}*/
	}
	
	public void updateActivity(Activity act)
	{
		Entity actE = null;
		try {
			actE = datastore.get(act.getKey());
		} catch (EntityNotFoundException e) {
			System.out.println("error entity not found//key::" + act.getKey() + "//startdate::" + act.getStartDate());
		}
		updateActEntity(actE, act);
		datastore.put(actE);
	}
	
	public List<Entity> getActivitiesEntityFiltered(Key key, Date Start, Date Stop) {
		Query qry = new Query("Activity");
		if (key != null)
			qry.setAncestor(key);
		qry.addFilter("StartDate", Query.FilterOperator.GREATER_THAN_OR_EQUAL, Start);
		qry.addFilter("StartDate", Query.FilterOperator.LESS_THAN_OR_EQUAL, Stop);
		qry.addSort("StartDate", Query.SortDirection.ASCENDING);
		List<Entity> pq = datastore.prepare(qry).asList(FetchOptions.Builder.withDefaults());
		return pq;
	}
	
	public List<Entity> getActivitiesEntityFiltered(Key key, String course) {
		Query qry = new Query("Activity");
		if (key != null)
			qry.setAncestor(key);
		qry.addFilter("CourseID", Query.FilterOperator.EQUAL, course);
		List<Entity> pq = datastore.prepare(qry).asList(FetchOptions.Builder.withDefaults());
		return pq;
	}
	
	public List<Entity> getActivitiesEntity(Key key, boolean last) {
		Query qry = new Query("Activity");
		if (key != null)
			qry.setAncestor(key);
		if (last){
			//qry.addFilter("StopDate", Query.FilterOperator.EQUAL, null);
			qry.addSort("StartDate", Query.SortDirection.DESCENDING);
		}
		List<Entity> pq = datastore.prepare(qry).asList(FetchOptions.Builder.withDefaults());
		/*if (last){
			if (!pq.isEmpty()){
				if ((Date)pq.get(0).getProperty("StopDate") != null){
					pq = null;
				}
			}
		}*/
		return pq;
	}
	
	public List<Question> getQuestionsByActivity(Key activityKey){
		Query q = new Query("Question");
		q.setAncestor(activityKey);
		List<Entity> pq = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
		System.out.println("retrieveactivitytest:" + pq);
		List<Question> listq = new ArrayList<Question>();
		for (int j = 0; j < pq.size(); j++){
			Entity qst = pq.get(j);
			Map<String, Object> qprops = qst.getProperties();
			listq.add(new Question(((Number)qprops.get("QuestionID")).intValue(), (String)qprops.get("Question"), (String)qprops.get("Answer"), (String)qprops.get("AnswerList")));
		}
		
		return listq;
	}
	
	
}
